import { Http } from '@/@nasty/Axios';
import { Principal } from '@/@nasty/Principal';
import { util } from '@/@nasty/Util';
import { SelectUserModel } from '@/@nasty/components/SelectUserModel';
import Upload from '@/@nasty/components/Upload';
import { PlusOutlined } from '@ant-design/icons';
import { ActionType, ModalForm, ProFormInstance, ProFormItem, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { Button, Checkbox, Divider, Modal, Table, TableProps, message } from 'antd';
import React, { forwardRef, useImperativeHandle } from 'react';
import { FC, cloneElement, useCallback, useRef, useState } from 'react';
import { CandidateMode } from './Common';

//标准流程状态，可继承进行扩展
const FlowStatus = {
    Wait: { Name: "待启动", Code: "FlowWait" },
    Start: { Name: "已启动", Code: "FlowStart" },
    End: { Name: "已完成", Code: "FlowEnd" },
    Approval: { Name: "审批中", Code: "FlowApproval" },
    Reject: { Name: "已驳回", Code: "FlowReject" },
    Revoke: { Name: "已撤销", Code: "FlowRevoke" }
}

const getFlowStatusName = (v: any) => {
    if (FlowStatus.Wait.Code == v) return FlowStatus.Wait.Name;
    if (FlowStatus.Start.Code == v) return FlowStatus.Start.Name;
    if (FlowStatus.End.Code == v) return FlowStatus.End.Name;
    if (FlowStatus.Approval.Code == v) return FlowStatus.Approval.Name;
    if (FlowStatus.Reject.Code == v) return FlowStatus.Reject.Name;
    if (FlowStatus.Revoke.Code == v) return FlowStatus.Revoke.Name;
    return "";
}

const columns: TableProps['columns'] = [
    {
        title: '节点名称',
        dataIndex: 'NodeName',
        align: "center",
        key: 'NodeName',
    },
    {
        title: '用户名称',
        dataIndex: 'UserName',
        align: "center",
        key: 'UserName',
    },
    {
        title: '节点动作',
        dataIndex: 'Action',
        align: "center",
        key: 'Action',
        render: (_, { Action }) => {
            if (Action == 1) return "同意"
            if (Action == 2) return "驳回"
            if (Action == 3) return "委派"
            if (Action == 9) return "撤销"
            return Action;
        }
    },
    {
        title: '备注',
        dataIndex: 'Remark',
        align: "center",
        key: 'Remark',
        render: (_, { Remark }) => {
            let text = Remark.replace("\n", "<br/>");
            return <div dangerouslySetInnerHTML={{ __html: text }}></div>
        }
    },
    {
        title: '操作时间',
        key: 'CreateTime',
        dataIndex: 'CreateTime',
        align: "center",
    }
];

async function SaveFlow(options: any) {
    return new Promise<any>((resolve, reject) => {
        Http.post("/Flow/Flow/SaveFlow", { ...options })
            .then((data) => {
                if (data.IsSuccess !== true)
                    reject(data.Message);
                else
                    resolve(data);
            }).catch((e) => {
                reject(e)
            })
    });
}

const FlowModel = forwardRef((props: any, ref) => {
    const { reload, disabled } = props;
    /*     const { values, trigger } = props; */
    const [isOpen, setIsOpen] = useState(false);
    const [isShowReject, setIsShowReject] = useState(false);
    const [isShowNext, setIsShowNext] = useState(false);
    const [isShowStart, setIsShowStart] = useState(false);
    const [isShowDelegate, setIsShowDelegate] = useState(false);
    const [isShowRevoke, setIsShowRevoke] = useState(false);
    const [logData, setLogData] = useState([]);
    const formRef = useRef<ProFormInstance>();
    const nextModelRef = React.useRef(null);
    const delegateModelRef = React.useRef(null);
    const rejectRef = React.useRef(null);
    const [messageApi, contextHolder] = message.useMessage();
    const [values, setValues] = useState(null);
    /**
     * @en-US International configuration
     * @zh-CN 国际化配置
     * */
    const intl = useIntl();
    const { run, loading } = useRequest(SaveFlow, {
        manual: true,
        onSuccess: () => {
            messageApi.success('提交成功');
            reload?.();
        },
        onError: (e: any) => {
            messageApi.error(e);
        },
    });

    // 定义可以被外部调用的 open 函数
    useImperativeHandle(ref, () => ({
        open: (v: any) => {
            setValues(v);
            setIsOpen(true);
            setTimeout(() => {
                load(v);
            }, 300)
        },
        close: () => {
            setIsOpen(false);
        }
    }));

    const load = (v: any = null) => {
        let data = v || values;
        Http.post("/Flow/Flow/GetFlow", { id: data.Id }).then((res) => {
            //等待开始
            if (!res) {
                formRef.current?.setFieldsValue({
                    Id: data.Id,
                    Name: data.Name,
                    FlowConfigCode: data.FlowConfigCode,
                    CurrentNodeName: "-"
                });

                setIsShowStart(true);
                setIsShowReject(false);
                setIsShowNext(false);
                setIsShowDelegate(false);
                setIsShowRevoke(false);
                return;
            }

            let userId = Principal.getUserInfo().Id;
            let approverIds = res.CurrentNode.ApproverIds || [];
            let completeApproverIds = res.CurrentNode.CompleteApproverIds || [];
            let isCompleteApproval = completeApproverIds.includes(userId);
            let isApprover = approverIds.includes(userId);
            let isCanApproval = !isCompleteApproval && isApprover;
            let isReject = res.CurrentNode.IsCanReject;
            let isNext = !res.IsEnd;
            let isShowDelegate = isNext && res.CurrentNode.Code != "Start";
            let isShowRevoke = isNext && res.CreateUserId == userId;

            setIsShowRevoke(isShowRevoke);
            setIsShowDelegate(isShowDelegate && isCanApproval)
            setIsShowReject(isReject && isCanApproval)
            setIsShowNext(isNext && isCanApproval);
            setIsShowStart(false);

            formRef.current?.setFieldsValue({
                Id: res.Id,
                Name: res.Name,
                CurrentNodeName: res.CurrentNode.Name,
            });


        }).catch((error) => {
            message.error(error);
        })

        loadLogData(data);
    }

    const loadLogData = (data: any) => {
        Http.post("/Flow/Flow/GetFlowLogs", { id: data.Id }).then((res) => {
            if (res) {
                setLogData(res);
            } else {
                message.error("流程审批记录加载失败");
            }

        }).catch((error) => {
            message.error(error);
        })
    }

    const startFlow = () => {
        let value = formRef.current?.getFieldsValue();
        run({ Id: value.Id, Name: value.Name, FlowConfigCode: value.FlowConfigCode })
            .then((res) => {
                //启用流程后刷新数据
                load();
            });
    }

    const revokeFlow = () => {
        let id = formRef.current?.getFieldValue("Id");
        Modal.confirm({
            title: '撤销',
            content: '确定撤销流程吗？',
            okText: '确认',
            cancelText: '取消',
            onOk: () => {
                Http.post("/Flow/Flow/RevokeFlow", { Id: id }).then((res) => {
                    if (res.IsSuccess) {
                        message.success('提交成功');
                    } else {
                        message.error(res.Message);
                    }

                    load();
                }).catch((error) => {
                    message.error('提交失败');
                })

            },
            onCancel: () => { },
        });
    };

    return (
        <>
            {contextHolder}
            <ModalForm
                title={"流程概览"}
                formRef={formRef}
                open={isOpen}
                width="700px"
                modalProps={{ okButtonProps: { loading }, onCancel: () => { setIsOpen(false); } }}
                onFinish={async (value) => {
                    //await run({ ...value });
                    return true;
                }}


                /*            onOpenChange={(v) => {
                               if (v) {
                                   load();
                               }
                           }} */
                submitter={{
                    render: (props, doms) => {
                        if (disabled) {
                            return [doms[0]];
                        }

                        return [
                            doms[0],
                            isShowRevoke ? <Button key="revoke" color="danger" variant="solid" onClick={revokeFlow}>
                                撤销
                            </Button> : null,
                            isShowStart ? <Button loading={loading} key="start" type="primary" onClick={startFlow}>
                                启动流程
                            </Button> : null,
                            isShowReject ? <Button key="reject" color="danger" variant="solid" onClick={() => {
                                let id = formRef.current?.getFieldValue("Id");
                                let nodeName = formRef.current?.getFieldValue("CurrentNodeName");
                                rejectRef.current.open({ Id: id, NodeName: nodeName });
                            }}>
                                驳回
                            </Button> : null,
                            isShowDelegate ? <Button key="delegate" type="primary" onClick={() => {
                                let id = formRef.current?.getFieldValue("Id");
                                let nodeName = formRef.current?.getFieldValue("CurrentNodeName");
                                delegateModelRef.current.open({ Id: id, NodeName: nodeName });
                            }}>
                                委派
                            </Button> : null,
                            isShowNext ? <Button key="next" type="primary" onClick={() => {
                                let id = formRef.current?.getFieldValue("Id");
                                nextModelRef.current.open({ Id: id });
                            }}>
                                下一步
                            </Button> : null,

                            /*    doms[1] */
                        ];
                    },
                }}
            >
                <ProFormText label="主键" name="Id" width={650} disabled hidden />
                <ProFormText label="流程配置编码" name="FlowConfigCode" width={650} disabled hidden />

                <ProFormText label="流程主体" name="Name" width={650} disabled />
                {/* <ProFormText label="流程状态" name="FlowStatusName" width={650} disabled /> */}
                <ProFormText label="当前节点" name="CurrentNodeName" width={650} disabled />

                <Table columns={columns} dataSource={logData} pagination={logData.length > 4 ? { pageSize: 4 } : false} />
                <NextModel ref={nextModelRef} onChange={() => { load(); }} />
                <DelegateModel ref={delegateModelRef} onChange={() => { load(); }} />
                <RejectModel ref={rejectRef} onChange={() => { load(); }} />
            </ModalForm>
        </>
    );
});

async function AgreeFlowNode(options: any) {
    return new Promise<any>((resolve, reject) => {
        Http.post("/Flow/Flow/AgreeFlowNode", { ...options })
            .then((data) => {
                if (data.IsSuccess !== true)
                    reject(data.Message);
                else
                    resolve(data);
            }).catch((e) => {
                reject(e)
            })
    });
}

const NextModel = forwardRef((props: any, ref) => {
    const [isOpen, setIsOpen] = useState(false);
    const [candidateMode, setCandidateMode] = useState(1);
    const [nextData, setNextData] = useState({ Candidates: [] });
    const [isShowUser, setIsShowUser] = useState(false);
    const [isShowNode, setIsShowNode] = useState(true);
    const [nodes, setNodes] = useState([]);
    const [users, setUsers] = useState([]);
    const [currentCandidate, setCurrentCandidate] = useState({});
    const [messageApi, contextHolder] = message.useMessage();

    /**
     * @en-US International configuration
     * @zh-CN 国际化配置
     * */
    const intl = useIntl();

    const formRef = React.useRef<ProFormInstance>(null);

    // 定义可以被外部调用的 open 函数
    useImperativeHandle(ref, () => ({
        open: (v: any) => {
            setIsOpen(true);
            load(v);
        },
        close: () => {
            setIsOpen(false);
        }
    }));

    const load = (v: any) => {
        Http.post("/Flow/Flow/GetFlowNextInfo", { Id: v.Id }).then((res) => {
            let data = res.Data || {};
            let nodes = data.NextNodes.map((t: any) => { return { label: t.Name, value: t.Id, code: t.Code } });
            let endNode = nodes.find((t: any) => t.code == "End");
            let lastNodeId = nodes.length == 1 ? nodes[0].value : null;

            setIsShowUser(!endNode);
            setIsShowNode(data.IsCanNext);
            setNextData(data);
            setNodes(nodes);

            formRef.current?.setFieldsValue({ Id: v.Id, NodeId: lastNodeId, UserIds: [], Remark: "" });

            if (lastNodeId) {
                onNodeChange(lastNodeId, data.Candidates);
            } else {
                setCandidateMode(0);
                setUsers([]);
            }
        }).catch((error) => {
            message.error('加载失败');
        })
    }

    const onNodeChange = (v: any, items: any = null) => {
        if (!v) return;
        let rows = items || nextData.Candidates || [];
        let candidate = rows.find((t: any) => t.NodeId == v);
        if (candidate == null) {
            setUsers([]);
        } else {
            setCandidateMode(candidate.CandidateMode);
            let items = candidate.Users.map((t: any) => { return { label: t.Name, value: t.Id } });
            setUsers(items);
        }

        setCurrentCandidate(candidate || {});
        formRef.current?.setFieldValue("UserIds", []);
    }

    const { run, loading } = useRequest(AgreeFlowNode, {
        manual: true,
        onSuccess: () => {
            messageApi.success('提交成功');
        },
        onError: (e: any) => {
            messageApi.error(e);
        },
    });

    return (
        <>
            {contextHolder}
            <ModalForm
                formRef={formRef}
                title={"下一步"}
                width="552px"
                open={isOpen}
                modalProps={{
                    onCancel: () => { setIsOpen(false); },
                }}
                onFinish={async (value) => {

                    let data = { ...value };
                    let userIds = data.UserIds || [];
                    data.UserIds = userIds.map((t: any) => t.value || t);

                    await run(data);
                    if (props.onChange) props.onChange();
                    setIsOpen(false);
                    return true;
                }}
            >
                <ProFormText label="流程Id" name="Id" width="xl" hidden></ProFormText>


                {isShowNode ? <ProFormSelect label="流程节点" name="NodeId" width="xl"
                    options={nodes}
                    onChange={(v) => { onNodeChange(v); }}
                    rules={[
                        {
                            required: true,
                            message: "流程节点必选",
                        },
                    ]}
                /> : null}

                {isShowUser && isShowNode && candidateMode == CandidateMode.User ? <SelectUserModel
                    onSelect={(row: any) => { formRef.current?.setFieldValue("UserIds", row); }}
                    defaultValue={() => { return formRef.current?.getFieldValue("UserIds") || []; }}
                    multiple={true}
                    openReload={true}
                    trigger={
                        <div>
                            <ProFormSelect
                                label="节点审批人"
                                name="UserIds"
                                mode="multiple"
                                rules={[{ required: true, message: "节点审批人必选", }]}
                                fieldProps={{ open: false, }}>
                            </ProFormSelect>
                        </div>
                    } /> : null}

                {isShowUser && isShowNode && (candidateMode == CandidateMode.PreUser || candidateMode == CandidateMode.Action) ? <ProFormSelect label="节点审批人" name="UserIds" width="xl"
                    options={users}
                    mode="multiple"
                    rules={[{ required: true, message: "节点审批人必选", },]}
                /> : null}

                {isShowUser && isShowNode && candidateMode == CandidateMode.Role ? <SelectUserModel
                    onSelect={(row: any) => { formRef.current?.setFieldValue("UserIds", row); }}
                    defaultValue={() => { return formRef.current?.getFieldValue("UserIds") || []; }}
                    multiple={true}
                    openReload={true}
                    params={{ RoleIds: currentCandidate.RoleIds }}
                    trigger={
                        <div>
                            <ProFormSelect
                                label="节点审批人"
                                name="UserIds"
                                mode="multiple"
                                rules={[{ required: true, message: "节点审批人必选", }]}
                                fieldProps={{ open: false, }}>
                            </ProFormSelect>
                        </div>
                    } /> : null}



                {isShowUser && isShowNode && candidateMode == CandidateMode.Department ? <SelectUserModel
                    onSelect={(row: any) => { formRef.current?.setFieldValue("UserIds", row); }}
                    defaultValue={() => { return formRef.current?.getFieldValue("UserIds") || []; }}
                    multiple={true}
                    openReload={true}
                    params={{ DepartmentIds: currentCandidate.DepartmentIds }}
                    trigger={
                        <div>
                            <ProFormSelect
                                label="节点审批人"
                                name="UserIds"
                                mode="multiple"
                                rules={[{ required: true, message: "节点审批人必选", }]}
                                fieldProps={{ open: false, }}>
                            </ProFormSelect>
                        </div>
                    } /> : null}

                <ProFormText label="备注" name="Remark" width="xl" />
            </ModalForm>
        </>
    );
});

async function RejectFlowNode(options: any) {
    return new Promise<any>((resolve, reject) => {
        Http.post("/Flow/Flow/RejectFlowNode", { ...options })
            .then((data) => {
                if (data.IsSuccess !== true)
                    reject(data.Message);
                else
                    resolve(data);
            }).catch((e) => {
                reject(e)
            })
    });
}

const RejectModel = forwardRef((props: any, ref) => {
    const [isOpen, setIsOpen] = useState(false);
    const [messageApi, contextHolder] = message.useMessage();

    /**
     * @en-US International configuration
     * @zh-CN 国际化配置
     * */
    const intl = useIntl();

    const formRef = React.useRef<ProFormInstance>(null);

    // 定义可以被外部调用的 open 函数
    useImperativeHandle(ref, () => ({
        open: (v: any) => {
            setIsOpen(true);
            setTimeout(() => {
                formRef.current?.setFieldsValue(v);
            }, 300)
        },
        close: () => {
            setIsOpen(false);
        }
    }));



    const { run, loading } = useRequest(RejectFlowNode, {
        manual: true,
        onSuccess: () => {
            messageApi.success('提交成功');
        },
        onError: (e: any) => {
            messageApi.error(e);
        },
    });

    return (
        <>
            {contextHolder}
            <ModalForm
                formRef={formRef}
                title={"驳回"}
                width="552px"
                open={isOpen}
                modalProps={{
                    onCancel: () => { setIsOpen(false); },
                }}
                onFinish={async (value) => {
                    await run({ ...value });
                    if (props.onChange) props.onChange();
                    setIsOpen(false);
                    return true;
                }}
            >
                <ProFormText label="流程Id" name="Id" width="xl" hidden></ProFormText>
                <ProFormText label="流程节点" name="NodeName" width="xl" disabled />
                <ProFormText label="备注" name="Remark" width="xl" />
            </ModalForm>
        </>
    );
});

async function DelegateFlowNode(options: any) {
    return new Promise<any>((resolve, reject) => {
        Http.post("/Flow/Flow/DelegateFlowNode", { ...options })
            .then((data) => {
                if (data.IsSuccess !== true)
                    reject(data.Message);
                else
                    resolve(data);
            }).catch((e) => {
                reject(e)
            })
    });
}

const DelegateModel = forwardRef((props: any, ref) => {
    const [isOpen, setIsOpen] = useState(false);
    const [messageApi, contextHolder] = message.useMessage();

    /**
     * @en-US International configuration
     * @zh-CN 国际化配置
     * */
    const intl = useIntl();

    const formRef = React.useRef<ProFormInstance>(null);

    // 定义可以被外部调用的 open 函数
    useImperativeHandle(ref, () => ({
        open: (v: any) => {
            setIsOpen(true);
            setTimeout(() => {
                formRef.current?.setFieldsValue(v);
            }, 300)
        },
        close: () => {
            setIsOpen(false);
        }
    }));



    const { run, loading } = useRequest(DelegateFlowNode, {
        manual: true,
        onSuccess: () => {
            messageApi.success('提交成功');
        },
        onError: (e: any) => {
            messageApi.error(e);
        },
    });

    return (
        <>
            {contextHolder}
            <ModalForm
                formRef={formRef}
                title={"委派"}
                width="552px"
                open={isOpen}
                modalProps={{
                    onCancel: () => { setIsOpen(false); },
                }}
                onFinish={async (value) => {
                    let userId = value.UserId.value;
                    let data = { ...value, UserId: userId };
                    await run(data);
                    if (props.onChange) props.onChange();
                    setIsOpen(false);
                    return true;
                }}
            >
                <ProFormText label="流程Id" name="Id" width="xl" hidden></ProFormText>
                <ProFormText label="流程节点" name="NodeName" width="xl" disabled />
                <SelectUserModel
                    onSelect={(row: any) => { formRef.current?.setFieldValue("UserId", row); }}
                    defaultValue={() => { return formRef.current?.getFieldValue("UserId") || []; }}
                    multiple={false}
                    trigger={
                        <div>
                            <ProFormSelect
                                label="用户"
                                name="UserId"
                                mode="single"
                                rules={[{ required: true }]}
                                fieldProps={{ open: false, }}>

                            </ProFormSelect>
                        </div>
                    } />
                <ProFormText label="备注" name="Remark" width="xl" />
            </ModalForm>
        </>
    );
});

export { FlowModel, FlowStatus, getFlowStatusName };